local siwang = fk.CreateSkill {
  name = "hanqing__siwang",
}

Fk:loadTranslationTable{
  ["hanqing__siwang"] = "伺望",
  [":hanqing__siwang"] = "出牌阶段限一次，你可以与所有角色共同拼点，你可以先令所有其他参与拼点的角色依次选择："..
  "1.将拼点牌交给你并退出本次拼点；2.与除你以外的另一名角色交换拼点牌。"..
  "若你赢，本回合你使用【杀】额外指定所有与你拼点牌颜色不同的角色为目标。",

  ["#hanqing__siwang"] = "伺望：与所有角色共同拼点，若赢，本回合使用【杀】指定所有拼点牌颜色不同的角色为目标",
  ["#hanqing__siwang-invoke"] = "伺望：是否令其他角色选择：交给你拼点牌并退出拼点，或与另一名角色交换拼点牌？",
  ["#hanqing__siwang-choose"] = "伺望：选择一名角色与其交换拼点牌，或点“取消”你的拼点牌将交给 %src 并退出本次拼点",
  ["hanqing__siwang_giveup"] = "退出拼点",
  ["#hanqing__siwang_exchange"] = "%from 选择 与%to交换拼点牌",
  ["@@hanqing__siwang-turn"] = "伺望",
}

local U = require "packages/utility/utility"

siwang:addEffect("active", {
  anim_type = "offensive",
  prompt = "#hanqing__siwang",
  card_num = 0,
  target_num = 0,
  can_use = function(self, player)
    return player:usedEffectTimes(siwang.name, Player.HistoryPhase) == 0 and
      table.find(Fk:currentRoom().alive_players, function (p)
        return player:canPindian(p)
      end)
  end,
  card_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = effect.from
    room:doIndicate(player, room:getOtherPlayers(player, false))
    local targets = table.filter(room:getOtherPlayers(player), function (p)
      return player:canPindian(p)
    end)
    if room:askToSkillInvoke(player, {
      skill_name = siwang.name,
      prompt = "#hanqing__siwang-invoke",
    }) then
      local dat = {}
      if #targets == 1 then
        table.insert(dat, {targets[1].id, targets[1].id})
        room:sendLog{
          type = "#Choice",
          from = targets[1].id,
          arg = "hanqing__siwang_giveup",
          toast = true,
        }
      else
        for _, p in ipairs(targets) do
          local others = table.filter(targets, function (q)
            return q ~= p
          end)
          local to = room:askToChoosePlayers(p, {
            min_num = 1,
            max_num = 1,
            targets = others,
            skill_name = siwang.name,
            prompt = "#hanqing__siwang-choose",
            cancelable = true,
          })
          if #to > 0 then
            table.insert(dat, {p.id, to[1].id})
            room:sendLog{
              type = "#hanqing__siwang_exchange",
              from = p.id,
              to = {to[1].id},
              toast = true,
            }
          else
            table.insert(dat, {p.id, p.id})
            room:sendLog{
              type = "#Choice",
              from = p.id,
              arg = "hanqing__siwang_giveup",
              toast = true,
            }
          end
        end
      end
      room:setBanner("hanqing__siwang-phase", dat)
    end
    local pindian = U.jointPindian(player, targets, siwang.name)
    room:setBanner("hanqing__siwang-phase", 0)
    if player.dead then return end
    if pindian.extra_data and pindian.extra_data.hanqing__siwang then
      local cards = table.filter(pindian.extra_data.hanqing__siwang, function (id)
        return room:getCardArea(id) == Card.Processing
      end)
      for _, id in ipairs(cards) do
        if player.dead then return end
        if room:getCardArea(id) == Card.Processing then
          room:moveCardTo(id, Card.PlayerHand, player, fk.ReasonJustMove, siwang.name, nil, true, player)
        end
      end
    end
    if pindian.winner == player and pindian.fromCard then
      for _, p in ipairs(pindian.tos) do
        if not p.dead and pindian.results[p].toCard and pindian.fromCard:compareColorWith(pindian.results[p].toCard, true) then
          room:addTableMarkIfNeed(p, "@@hanqing__siwang-turn", player.id)
        end
      end
    end
  end,
})

siwang:addEffect(fk.PindianCardsDisplayed, {
  can_refresh = function(self, event, target, player, data)
    return data.from == player and data.reason == siwang.name and player.room:getBanner("hanqing__siwang-phase")
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    local dat = room:getBanner("hanqing__siwang-phase")
    for _, info in ipairs(dat) do
      if info[1] ~= info[2] then
        local p = room:getPlayerById(info[1])
        local to = room:getPlayerById(info[2])
        data.results[p].toCard, data.results[to].toCard = data.results[to].toCard, data.results[p].toCard
      end
    end
    local cards = {}
    for _, info in ipairs(dat) do
      if info[1] == info[2] then
        local p = room:getPlayerById(info[1])
        table.removeOne(data.tos, p)
        if data.results[p].toCard then
          table.insertIfNeed(cards, data.results[p].toCard:getEffectiveId())
        end
        data.results[p] = nil
      end
    end
    data.extra_data = data.extra_data or {}
    data.extra_data.hanqing__siwang = cards
  end,
})

siwang:addEffect(fk.AfterCardTargetDeclared, {
  anim_type = "offensive",
  is_delay_effect = true,
  can_trigger = function(self, event, target, player, data)
    if target == player and data.card.trueName == "slash" then
      local targets = table.filter(player.room:getOtherPlayers(player), function(p)
        return table.contains(p:getTableMark("@@hanqing__siwang-turn"), player.id) and
          table.contains(data:getExtraTargets({ bypass_distances = true }), p)
      end)
      if #targets > 0 then
        event:setCostData(self, {extra_data = targets})
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    for _, p in ipairs(event:getCostData(self).extra_data) do
      player.room:doIndicate(player, {p})
      data:addTarget(p)
    end
  end,
})

return siwang
